package net.mcreator.toolsasfood.procedures;

import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent;

import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.projectile.Arrow;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Entity;
import net.minecraft.server.level.ServerLevel;

import net.mcreator.toolsasfood.init.ToolsAsFoodModMobEffects;

import javax.annotation.Nullable;

@Mod.EventBusSubscriber
public class BowSummonsProcedure {
	@SubscribeEvent
	public static void onUseItemStart(LivingEntityUseItemEvent.Stop event) {
		if (event != null && event.getEntity() != null) {
			Entity entity = event.getEntity();
			execute(event, entity.level, entity.getX(), entity.getY(), entity.getZ(), entity, event.getItem());
		}
	}

	public static void execute(LevelAccessor world, double x, double y, double z, Entity entity, ItemStack itemstack) {
		execute(null, world, x, y, z, entity, itemstack);
	}

	private static void execute(@Nullable Event event, LevelAccessor world, double x, double y, double z, Entity entity, ItemStack itemstack) {
		if (entity == null)
			return;
		double fx = 0;
		double fy = 0;
		double mod = 0;
		double fz = 0;
		if ((entity instanceof LivingEntity _livEnt ? _livEnt.hasEffect(ToolsAsFoodModMobEffects.BOW_SUMMON_ARROW) : false)
				&& (itemstack.getItem() == Items.CROSSBOW || itemstack.getItem() == Items.BOW)) {
			fx = entity.level.clip(new ClipContext(entity.getEyePosition(1f), entity.getEyePosition(1f).add(entity.getViewVector(1f).scale(100)),
					ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity)).getBlockPos().getX() - x;
			fy = entity.level.clip(new ClipContext(entity.getEyePosition(1f), entity.getEyePosition(1f).add(entity.getViewVector(1f).scale(100)),
					ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity)).getBlockPos().getY() - (y + 1.5);
			fz = entity.level.clip(new ClipContext(entity.getEyePosition(1f), entity.getEyePosition(1f).add(entity.getViewVector(1f).scale(100)),
					ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity)).getBlockPos().getZ() - z;
			mod = Math.pow(Math.pow(fx, 2) + Math.pow(fy, 2) + Math.pow(fz, 2), 0.5);
			fx = (fx / mod) * 5;
			fy = (fy / mod) * 5;
			fz = (fz / mod) * 5;
			if (world instanceof ServerLevel _level) {
				Entity entityToSpawn = new Arrow(EntityType.ARROW, _level);
				entityToSpawn.moveTo(x, (y + 1.5), z, entity.getYRot(), entity.getXRot());
				entityToSpawn.setYBodyRot(entity.getYRot());
				entityToSpawn.setYHeadRot(entity.getYRot());
				entityToSpawn.setDeltaMovement(fx, fy, fz);
				if (entityToSpawn instanceof Mob _mobToSpawn)
					_mobToSpawn.finalizeSpawn(_level, world.getCurrentDifficultyAt(entityToSpawn.blockPosition()), MobSpawnType.MOB_SUMMONED, null,
							null);
				world.addFreshEntity(entityToSpawn);
			}
		}
	}
}
